#include <Kharlia/Engine/Common.h>
#include <Kharlia/Engine/Init.h>
#include <Kharlia/Engine/Client.h>
#include <CEGUIWindow.h>

//namespace kharlia { namespace engine {
//
//struct FUIWindowPtr {
//    ui::Window* Ptr;
//    TWeakPtr<CClient> Owner;
//
//    FUIWindowPtr(ui::Window* p):
//        Ptr(p) {}
//};
//
//ui::Window* get_pointer(FUIWindowPtr const& p) {
//    return p.Owner.GetHandle() ? (p.Owner.Lock() ? p.Ptr : nullptr) : p.Ptr;
//}
//
//}}
//
//namespace boost { namespace python {
//
//template <>
//struct pointee<kharlia::engine::FUIWindowPtr> {
//    typedef kharlia::ui::Window type;
//};
//
//}}

namespace kharlia { namespace engine {

void _InitClientBindings() {
    {

    using namespace ui;

    class_<Window, noncopyable>
        ("CUIWindow", no_init)
        .add_property("Type", make_function(&Window::getType, return_value_policy<return_by_value>()))
        .add_property("Name", make_function(&Window::getName, return_value_policy<return_by_value>()))
        .def("IsDisabled", &Window::isDisabled, (arg("localOnly")=false))
        .add_property("Text", make_function(&Window::getText, return_value_policy<return_by_value>()),
                              &Window::setText)
        .add_property("Position", make_function(&Window::getPosition, return_value_policy<return_by_value>()),
                                  &Window::setPosition)
        .add_property("Size", make_function(&Window::getSize, return_value_policy<return_by_value>()),
                              &Window::setSize)
        .def("AddChildWindow", (void (Window::*)(String const&))&Window::addChildWindow)
        .def("AddChildWindow", (void (Window::*)(Window*))&Window::addChildWindow)
        // PropertySet
        .def("GetProperty", &Window::getProperty, (arg("name")))
        .def("SetProperty", &Window::setProperty, (arg("name"), arg("value")))
        .def("IsPropertyDefault", &Window::isPropertyDefault, (arg("name")))
        .def("GetPropertyDefault", &Window::getPropertyDefault, (arg("name")))
        // EventSet
        ;

    }

    class_<CUIScriptModule, bases<core::CObject>, noncopyable>
        ("CUIScriptModuleBase", init<>())
        ;

    class_<CClient, bases<core::CObject>, noncopyable>
        ("CClientBase", init<>())
        .add_property("Engine", &CClient::GetEngine)
        .def_readonly("WindowHandle", &CClient::mWindowHandle)
        .def_readwrite("ShowActorBounds", &CClient::mShowActorBounds)
        .add_property("Camera", &CClient::GetCamera, &CClient::SetCamera)
        .add_property("ViewportSize", make_getter(&CClient::mViewportSize), &CClient::SetViewportSize)
        .add_property("Time", &CClient::GetTime)
        .add_property("RenderCamera", &CClient::GetRenderCamera)
        .add_property("InitedUI", &CClient::GetInitedUI)
        .def("Tick", &CClient::Tick)
        .def("DrawViewport", &CClient::DrawViewport)
        .def("Exec", &CClient::ExecImpl)
        .def("PrintLine", (void (CClient::*)(unicode))&CClient::PrintLine)
        .def("PrintLine", (void (CClient::*)(str))&CClient::PrintLine)
        .def("IsKeyPressed", &CClient::IsKeyPressed)
        .def("InputKeyDown", &CClient::InputKeyDown)
        .def("InputKeyUp", &CClient::InputKeyUp)
        .def("InputChar", &CClient::InputChar)
        .def("InputMouseButtonDown", &CClient::InputMouseButtonDown)
        .def("InputMouseButtonUp", &CClient::InputMouseButtonUp)
        .def("InputMousePosition", &CClient::InputMousePosition)
        .def("ConvertScreenToTileCoords", &CClient::ConvertScreenToTileCoords)
        .def("LoadTexture", &CClient::LoadTexture)
        .def("CreateTexture", (shared_ptr<FTexture> (CClient::*)(str))&CClient::CreateTexture)
        .def("CreateTexture", (shared_ptr<FTexture> (CClient::*)(str, str))&CClient::CreateTexture)
        .def("GetTexture", &CClient::GetTexture, (arg("name"), arg("filename")=object()))
        .def("CreateWindow", &CClient::CreateWindow, return_value_policy<reference_existing_object, with_custodian_and_ward_postcall<1, 0>>(), (arg("type"), arg("name")=str()))
        .def("GetWindow", &CClient::GetWindow, return_value_policy<reference_existing_object, with_custodian_and_ward_postcall<1, 0>>(), (arg("name")))
        .def("IsWindowPresent", &CClient::IsWindowPresent)
        .def("DestroyWindow", (void (CClient::*)(str))&CClient::DestroyWindow)
        .def("DestroyWindow", (void (CClient::*)(ui::Window*))&CClient::DestroyWindow)
        ;

    RegisterPtrConverter<CClient>();
    KH_IMPL_GC(CClient);
}

}}